﻿Imports Microsoft.Office.Interop.Excel
'Imports Microsoft
'Imports Microsoft.Office.Interop
'Imports System.Reflection
'Imports System.Runtime.InteropServices

Public Class clsGeneral

    Public Function CheckedListBox_a_Hilera(ByRef po_CheckedListBox As CheckedListBox) As String
        CheckedListBox_a_Hilera = ""
        Dim itemChecked As Object
        For Each itemChecked In po_CheckedListBox.CheckedItems
            CheckedListBox_a_Hilera = CheckedListBox_a_Hilera & itemChecked.Row.ItemArray(0).ToString & ","
        Next
        If CheckedListBox_a_Hilera <> "" Then
            CheckedListBox_a_Hilera = "," & CheckedListBox_a_Hilera
        End If
    End Function

    Public Sub CheckedListBox_Limpiar(ByRef po_ListBox As CheckedListBox)
        Dim i As Integer

        For i = 0 To po_ListBox.Items.Count - 1
            po_ListBox.SetItemChecked(i, False)
        Next
    End Sub

    Public Sub CheckedListbox_Marcar(ByRef po_CheckedListBox As CheckedListBox, ByRef ps_ListaValores As String)
        ' selecciona y marca en un Checked los valores dados en una ListaValores
        Dim i As Integer
        Dim Lista As String
        Dim ls_Codigo As String
        Dim Fila As DataRowView

        Lista = ps_ListaValores
        While Len(Lista) > 0
            ls_Codigo = Me.Extrae_Valor_de_Lista(Lista)
            For i = 0 To po_CheckedListBox.Items.Count - 1
                Fila = po_CheckedListBox.Items(i)
                If Fila.Item(0) = ls_Codigo Then
                    po_CheckedListBox.SetItemChecked(i, True)
                    Exit For
                End If
            Next
        End While
    End Sub

    Public Function Convertir_A_String(ByVal Numero As Long, ByVal Largo As Integer)
        ' recibe un número y lo convierte a String reemplazando los blancos iniciales por ceros hasta completar el tamaño indicado
        Dim li_Faltan As Integer
        Dim li_Contador As Integer
        Convertir_A_String = Trim(Str(Numero))
        li_Faltan = (Largo - Len(Convertir_A_String))
        For li_Contador = 1 To li_Faltan
            Convertir_A_String = "0" & Convertir_A_String
        Next
    End Function

    Public Sub DataTable_a_Excel(ByVal MiDataTable As System.Data.DataTable, ByRef BarraProgreso As ProgressBar)
        ' http://vbnetsqlserver.wordpress.com/2012/06/27/exportar-de-un-datatable-a-excel/
        ' requiere referencias a Ensamblados\Extensiones\Microsoft.Office.Interop.Excel.dll y Microsoft.Vbe.Interop.dll
        Dim Excel As Object = CreateObject("Excel.Application")
        Dim DataRow As System.Data.DataRow
        Dim Columna As Integer = 0
        Dim Fila As Integer = 0

        If Excel Is Nothing Then
            MsgBox("Error. Es posible que Excel no esté instalado en su máquina, y es requerido para realizar esta operación.", MsgBoxStyle.Critical)
            Return
        End If
        Try
            Excel.SheetsInNewWorkbook = 1
            Excel.Workbooks.Add()
            Excel.Worksheets(1).Select()

            ' carga la primera fila de Excel con los nombres de las columnas del DataTable
            For Each DataColum In MiDataTable.Columns
                Columna = Columna + 1
                Excel.Cells(1, Columna) = DataColum.ColumnName
            Next
            Excel.Worksheets(1).Rows.Item(1).Font.Bold = 1

            ' carga las siguientes filas de Excel con los datos del DataTable
            BarraProgreso.Maximum = MiDataTable.Rows.Count
            BarraProgreso.Value = 0
            BarraProgreso.Visible = True
            For Each DataRow In MiDataTable.Rows
                Fila = Fila + 1
                Columna = 0
                For Each DataColum In MiDataTable.Columns
                    Columna = Columna + 1
                    Excel.Cells(Fila + 1, Columna) = DataRow(DataColum.ColumnName)
                Next
                BarraProgreso.Value += 1
            Next
            Excel.Worksheets(1).Columns.AutoFit()

            ' guarda la hoja Excel como documento destino y lo abre para el usuario
            BarraProgreso.Visible = False
            Excel.Visible = True
            Excel = Nothing

        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
    End Sub

    'Public Sub DataTable_Cargar_Lista(ByRef po_Lista As Object, ByRef dt As System.Data.DataTable, ByVal ps_Todos As String)
    '    ' PROBLEMA: cuando la tabla tiene llave primaria Tinyint (0-255) NO permite hacer hacer referencia a valor -1
    '    '--------------------------------------'
    '    ' po_Lista puede ser ComboBox o ListBox '
    '    '--------------------------------------'
    '    Dim NuevaFila As DataRow

    '    po_Lista.DataSource = Nothing
    '    po_Lista.Items.Clear()

    '    If ps_Todos.Trim <> "" Then
    '        NuevaFila = dt.NewRow
    '        ' asume que el valor de Llave Primaria está en la columna 0
    '        NuevaFila.Item(dt.Columns(0).ColumnName) = -1  ' para que uspSELECT.WHERE invocado traiga TODOS los registros
    '        ' asume que el valor de Descripción está en la columna 1
    '        NuevaFila.Item(dt.Columns(1).ColumnName) = "." & ps_Todos   ' el "." para que aparezca de primero en la lista ordenada
    '        dt.Rows.Add(NuevaFila)
    '        ' reordena el DataTable
    '        dt = dt.Select(Nothing, dt.Columns(1).ColumnName & " asc").CopyToDataTable()
    '    End If

    '    po_Lista.DataSource = dt
    '    ' asume que el valor de Llave Primaria está en la columna 0
    '    po_Lista.ValueMember = dt.Columns(0).ToString()
    '    ' asume que el valor de Descripción está en la columna 1
    '    po_Lista.DisplayMember = dt.Columns(1).ToString()
    '    ' posiciona el primer elemento de la lista
    '    If po_Lista.Items.Count > 0 Then
    '        po_Lista.SelectedIndex = 0
    '    End If
    'End Sub

    Sub DataTable_Cargar_Lista_Manual(ByRef po_Lista As Object, ByRef dt As System.Data.DataTable, ByVal ps_Todos As String)
        '--------------------------------------'
        ' po_Lista puede ser ComboBox o ListBox '
        '--------------------------------------'
        ' se crea este procedimiento para los ComboBox en formularios de consulta cuando la tabla 
        ' tiene llave primaria de tipo Tinyint (0-255) y se requiere usar -1 = Todos

        Dim Tabla_Manual As System.Data.DataTable
        Tabla_Manual = New System.Data.DataTable()

        ' asume que el valor de Llave Primaria está en la columna 0
        Dim Col_Int As DataColumn = New DataColumn("Col_Int")
        Col_Int.DataType = System.Type.GetType("System.Int32")

        ' asume que el valor de Descripción está en la columna 1
        Dim Col_String As DataColumn = New DataColumn("Col_String")
        Col_String.DataType = System.Type.GetType("System.String")

        Tabla_Manual.Columns.Add(Col_Int)
        Tabla_Manual.Columns.Add(Col_String)

        Dim NuevaFila As DataRow

        If ps_Todos.Trim <> "" Then
            NuevaFila = Tabla_Manual.NewRow()
            NuevaFila("Col_Int") = -1  ' para que uspSELECT.WHERE invocado traiga TODOS los registros
            NuevaFila("Col_String") = ps_Todos
            Tabla_Manual.Rows.Add(NuevaFila)
        End If

        ' carga manualmente los registros de la tabla parámetro
        For i As Integer = 0 To dt.Rows.Count - 1
            NuevaFila = Tabla_Manual.NewRow()
            NuevaFila("Col_Int") = dt.Rows(i).Item(0)
            NuevaFila("Col_String") = dt.Rows(i).Item(1)
            Tabla_Manual.Rows.Add(NuevaFila)
        Next

        po_Lista.DataSource = Tabla_Manual
        ' asume que el valor de Llave Primaria está en la columna 0
        po_Lista.ValueMember = Tabla_Manual.Columns(0).ToString()
        ' asume que el valor de Descripción está en la columna 1
        po_Lista.DisplayMember = Tabla_Manual.Columns(1).ToString()
        ' posiciona el primer elemento de la lista
        If po_Lista.Items.Count > 0 Then
            po_Lista.SelectedIndex = 0
        End If
    End Sub

    Public Function DataTable_Existe_en(ByRef dt As System.Data.DataTable, ByVal codigo As Long) As Boolean
        ' OPCION 1: busca un valor por Llave Primaria en un DataTable, pero debe construir la Llave Primaria
        'Dim Col_PK(1) As DataColumn
        'Col_PK(0) = dt.Columns(0)
        'dt.PrimaryKey = Col_PK
        'Dim FilaEncontrada As DataRow = dt.Rows.Find(codigo)

        ' OPCION 2: busca un valor en una columna determinada, se asume col(0) como Llave Primaria
        Dim FilaEncontrada() As DataRow = dt.Select(dt.Columns(0).ColumnName & " = " & codigo)

        If FilaEncontrada.Count <> 0 Then
            DataTable_Existe_en = True
        Else
            DataTable_Existe_en = False
        End If

        ' OPCION 3: lo que sigue es más ineficiente pues el recorrido se realiza manualmente
        'DataTable_Existe_en = False
        'For i As Integer = 0 To dt.Rows.Count - 1
        '    If dt.Rows(i).Item(0) = codigo Then
        '        DataTable_Existe_en = True
        '        Exit For
        '    End If
        'Next
    End Function

    Public Function DataTable_Filtrar_Ordenar(ByRef dt As System.Data.DataTable, SQL_Filtrado As String, Col_Ordenar_ASC As String) As System.Data.DataTable
        '-------------------------------------------------------------------------------------------------------------------------
        '-- Se programa esta función para dejar intacto un DataTable original y que NO se vea afectado en un DataSouce/DabaBinding --
        '-------------------------------------------------------------------------------------------------------------------------
        ' SQL_Filtrado es una condición SQL, por ejemplo "col = valor" , "col LIKE '%valor%'" , "col > valor"
        ' Col_Ordenar_ASC es el nombre de columna por la cual ordenar ASCendentemente
        If SQL_Filtrado.Trim <> "" And Col_Ordenar_ASC.Trim <> "" Then
            DataTable_Filtrar_Ordenar = dt.Select(SQL_Filtrado, Col_Ordenar_ASC & " asc").CopyToDataTable()
        ElseIf SQL_Filtrado.Trim = "" And Col_Ordenar_ASC.Trim <> "" Then
            DataTable_Filtrar_Ordenar = dt.Select(Nothing, Col_Ordenar_ASC & " asc").CopyToDataTable()
        ElseIf SQL_Filtrado.Trim <> "" And Col_Ordenar_ASC.Trim = "" Then
            DataTable_Filtrar_Ordenar = dt.Select(SQL_Filtrado, Nothing).CopyToDataTable()
        Else    ' no debería darse este caso pero por probabilidad matemática se programa
            DataTable_Filtrar_Ordenar = dt
        End If
    End Function

    Public Function Extrae_Valor_de_Lista(ByRef ListaValores As String) As String
        ' recibe una lista de valores separados por comas, extrae el primero de ellos y lo quita de la lista de valores
        Dim Valor As String
        Dim Posicion As Integer

        ' elimina comas inicial y final si las hubiera
        If Microsoft.VisualBasic.Left(ListaValores, 1) = "," Then
            ListaValores = Microsoft.VisualBasic.Mid(ListaValores, 2, Len(ListaValores))
        End If
        If Microsoft.VisualBasic.Right(ListaValores, 1) = "," Then
            ListaValores = Microsoft.VisualBasic.Mid(ListaValores, 1, Len(ListaValores) - 1)
        End If

        ' extrae el valor y actualiza la lista de valores
        Posicion = InStr(ListaValores, ",")
        If Posicion = 0 Then Posicion = Len(ListaValores) + 1 ' para que "crea" que hay una coma final
        Valor = Microsoft.VisualBasic.Left(ListaValores, Posicion - 1)
        ListaValores = Microsoft.VisualBasic.Mid(ListaValores, Posicion + 1, Len(ListaValores))

        Return Valor
    End Function

    Function SoloNumeros(ByVal Keyascii As Short) As Short
        If InStr("1234567890", Chr(Keyascii)) = 0 Then
            SoloNumeros = 0
        Else
            SoloNumeros = Keyascii
        End If
        Select Case Keyascii
            Case 8
                SoloNumeros = Keyascii
            Case 13
                SoloNumeros = Keyascii
        End Select
    End Function

    'Public Function ValidarFechas(ByVal Fecha1 As DateTimePicker, ByVal Fecha2 As DateTimePicker, ByVal TextoError As String) As Boolean
    '    If (Fecha1.Value.Date > Fecha2.Value.Date) Then
    '        MessageBox.Show(TextoError, "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1)
    '        Return False
    '    Else
    '        Return True
    '    End If
    'End Function

End Class
